package com.godenwater.recv.server.sl651;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.serial.SerialAddress;
import org.apache.mina.transport.serial.SerialConnector;
import org.apache.mina.transport.serial.SerialAddress.DataBits;
import org.apache.mina.transport.serial.SerialAddress.FlowControl;
import org.apache.mina.transport.serial.SerialAddress.Parity;
import org.apache.mina.transport.serial.SerialAddress.StopBits;
import org.apache.mina.transport.socket.DatagramSessionConfig;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioDatagramAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.godenwater.core.container.BasicModule;

public class ConnectionManager extends BasicModule {

    private static Logger logger = LoggerFactory
            .getLogger(ConnectionManager.class);

    private static int DEFAULT_SERVER_PORT = 20000;
    // 创建一个非阻塞式的服务端，默认打开一个创建此对象
    private NioSocketAcceptor tcpAcceptor;
    private NioDatagramAcceptor udpAcceptor;// = new NioDatagramAcceptor();

    private IoConnector gsmConnector;// = new SerialConnector();
    private IoConnector pstnConnector;// = new SerialConnector();

    public ConnectionManager() {
        super("Connection Manager");
        // TODO Auto-generated constructor stub
    }

    @Override
    public void start() {
        super.start();
        startTcpListener();
        startUdpListener();
        startGsmListener();
        startPstnListener();
    }

    @Override
    public void stop() {
        super.stop();
        stopTcpListener();
        stopUdpListener();
        stopGsmListener();
        stopPstnListener();
    }

    public boolean isTcpListenerEnabled() {
        return true;
    }

    public int getTcpListenerPort() {
        return DEFAULT_SERVER_PORT;// JiveGlobals.getIntProperty("xmpp.server.socket.port",
        // DEFAULT_SERVER_PORT);
    }

    public void setTcpListenerPort(int port) {
        if (port == getTcpListenerPort()) {
            // Ignore new setting
            return;
        }
        // JiveGlobals.setProperty("xmpp.server.socket.port",
        // String.valueOf(port));
        // Stop the port listener for s2s communication
        stopTcpListener();
        if (isTcpListenerEnabled()) {
            try {
                Thread.sleep(5 * 1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // Start the port listener for s2s communication
            startTcpListener();
        }
    }

    private void startTcpListener() {

        tcpAcceptor = new NioSocketAcceptor();
        int PORT = HydroConfig.getHydroGprsTcpPort();
        System.out.println(">> tcp port " + PORT);
        // The logger, if needed. Commented atm
        DefaultIoFilterChainBuilder chain = tcpAcceptor.getFilterChain();
        // chain.addLast("logger", new LoggingFilter());
        chain.addLast("protocol", new ProtocolCodecFilter(
                new HydroCodecFactory(true)));

        // 增加一个数据处理缓存线程池
        // chain.addLast("dbThreadpool", new
        // ExecutorFilter(Executors.newCachedThreadPool()));

        // LoggingFilter loggingFilter = new LoggingFilter();
        // chain.addLast("logging", loggingFilter);

        tcpAcceptor.setHandler(new ServerDataHandler(HydroServer.getInstance(), "TCP", PORT));
        // 设置读取数据的缓冲区大小
        tcpAcceptor.getSessionConfig().setReadBufferSize(65536); // 针对最大报文的缓冲设置

        // 读写通道30秒内无操作进入空闲状态
        tcpAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 40);

        SocketSessionConfig dcfg = tcpAcceptor.getSessionConfig();
        dcfg.setReuseAddress(true);

        try {
            tcpAcceptor.bind(new InetSocketAddress(PORT));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void stopTcpListener() {
        if (tcpAcceptor != null) {
            System.out.println("正在关闭TCP连接");
            tcpAcceptor.unbind();
            tcpAcceptor = null;
        }
    }

    // ---------------------------------------------

    private void startUdpListener() {

        // if (HydroConfig.getGprsUdpEnabled()) {

        int PORT = HydroConfig.getHydroGprsUdpPort();
        System.out.println(">> udp port " + PORT);
        udpAcceptor = new NioDatagramAcceptor();

        // The logger, if needed. Commented atm
        DefaultIoFilterChainBuilder chain = udpAcceptor.getFilterChain();
        chain.addLast("protocol", new ProtocolCodecFilter(
                new HydroCodecFactory(true)));

        // 增加一个数据处理缓存线程池
        // chain.addLast("dbThreadpool", new
        // ExecutorFilter(Executors.newCachedThreadPool()));

        //chain.addLast("logging", new LoggingFilter());

        udpAcceptor.setHandler(new ServerDataHandler(HydroServer.getInstance(), "udp", PORT));
        // 设置读取数据的缓冲区大小
        udpAcceptor.getSessionConfig().setReadBufferSize(2048);
        // 读写通道30秒内无操作进入空闲状态
        udpAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 30);

        DatagramSessionConfig dcfg = udpAcceptor.getSessionConfig();
        dcfg.setReuseAddress(true);
        try {
            udpAcceptor.bind(new InetSocketAddress(PORT));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // }
    }

    private void stopUdpListener() {
        if (udpAcceptor != null) {
            udpAcceptor.unbind();
            udpAcceptor = null;
        }
    }

    private void startGsmListener() {

        if (HydroConfig.isHydroGsmEnabled()) {
            gsmConnector = new SerialConnector();
            // /dev/ttyS0
            SerialAddress portAddress = new SerialAddress(
                    HydroConfig.getHydroGsmSerial(),
                    HydroConfig.getHydroGsmBaudRate(), DataBits.DATABITS_8,
                    StopBits.BITS_1, Parity.NONE, FlowControl.NONE);

            // ==========================================

            DefaultIoFilterChainBuilder chain = gsmConnector.getFilterChain();
            // chain.addLast("logger", new LoggingFilter());
            chain.addLast("protocol", new ProtocolCodecFilter(
                    new HydroCodecFactory(true)));

            // 增加一个数据处理缓存线程池
            // chain.addLast("dbThreadpool", new
            // ExecutorFilter(Executors.newCachedThreadPool()));

            // LoggingFilter loggingFilter = new LoggingFilter();
            // chain.addLast("logging", loggingFilter);

            gsmConnector.setHandler(new ServerDataHandler(HydroServer.getInstance(), "COMM", 15210));
            // 设置读取数据的缓冲区大小
            gsmConnector.getSessionConfig().setReadBufferSize(
                    HydroConfig.getBufferSize()); // 针对最大报文的缓冲设置

            // 读写通道30秒内无操作进入空闲状态
            gsmConnector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
                    40);

            // ===========================================

            try {
                ConnectFuture future = gsmConnector.connect(portAddress);

                future.await();

                // IoSession sessin = future.getSession();

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private void stopGsmListener() {
        if (gsmConnector != null) {
            gsmConnector.dispose();
            gsmConnector = null;
        }
    }

    private void startPstnListener() {
        if (HydroConfig.isHydroPstnEnabled()) {
            pstnConnector = new SerialConnector();
            // /dev/ttyS0
            SerialAddress portAddress = new SerialAddress(
                    HydroConfig.getHydroPstnSerial(),
                    HydroConfig.getHydroPstnBaudRate(), DataBits.DATABITS_8,
                    StopBits.BITS_1, Parity.NONE, FlowControl.NONE);

            // ==========================================

            DefaultIoFilterChainBuilder chain = pstnConnector.getFilterChain();
            // chain.addLast("logger", new LoggingFilter());
            chain.addLast("protocol", new ProtocolCodecFilter(
                    new HydroCodecFactory(true)));

            // 增加一个数据处理缓存线程池
            // chain.addLast("dbThreadpool", new
            // ExecutorFilter(Executors.newCachedThreadPool()));

            // LoggingFilter loggingFilter = new LoggingFilter();
            // chain.addLast("logging", loggingFilter);

            pstnConnector.setHandler(new ServerDataHandler(HydroServer.getInstance(), "PSTN", 15210));
            // 设置读取数据的缓冲区大小
            pstnConnector.getSessionConfig().setReadBufferSize(
                    HydroConfig.getBufferSize()); // 针对最大报文的缓冲设置

            // 读写通道30秒内无操作进入空闲状态
            pstnConnector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE,
                    40);

            // ===========================================

            try {
                ConnectFuture future = pstnConnector.connect(portAddress);

                future.await();

                // IoSession sessin = future.getSession();

            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private void stopPstnListener() {
        if (pstnConnector != null) {
            pstnConnector.dispose();
            pstnConnector = null;
        }
    }

    public static void main(String[] args) {
        SerialConnector connector = new SerialConnector();

        DefaultIoFilterChainBuilder chain = connector.getFilterChain();
        chain.addLast("protocol", new ProtocolCodecFilter(
                new HydroCodecFactory(true)));
        LoggingFilter loggingFilter = new LoggingFilter();
        connector.getFilterChain().addLast("logging", loggingFilter);

        // connector.getFilterChain().addLast("codec",
        // new ProtocolCodecFilter(new TextLineCodecFactory()));
        connector.setHandler(new CommDataHandler("COMM"));// DataBits dataBits,
        // StopBits
        // stopBits, Parity
        // parity,
        // FlowControl
        // flowControl
        SerialAddress portAddress = new SerialAddress("COM7", 9600,
                DataBits.DATABITS_8, StopBits.BITS_1, Parity.NONE,
                FlowControl.NONE);
        ConnectFuture future = connector.connect(portAddress);
        // try {
        // // future.await();
        // // IoSession session = future.getSession();
        //
        // } catch (InterruptedException e) {
        // e.printStackTrace();
        // }
        IoSession session = future.getSession();
        // sessin.getFilterChain().addFirst("first", new addfilter());
        IoSessionConfig sc = session.getService().getSessionConfig();
        session.setAttribute("comname", "COM5");
        String hexString = "AT/r";

        System.out.println(hexString);
        // byte[] b = ByteUtil.HexStringToBinary(hexString);
        session.write(hexString.getBytes());
        // connector.dispose();
    }

}
